package lucene;

import com.alibaba.fastjson.JSON;
import lucene.IKAnalyzer5x.IKAnalyzer5x;
import lucene.IKAnalyzer5x.IKSynonymsAnalyzer5x;
import lucene.utils.FileUtil;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.*;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by User on 2017/11/29.
 */
public class App {

    static final String indexPath = "E:\\lucene\\index";

    static final String indexPath2 = "E:\\lucene\\index2";


    public static void main(String[] args) throws Exception {

        App app = new App();
        app.testIKSyn("女鞋,女鞋,女鞋,女靴");
    }

    private void testIKSyn(String word) throws IOException {
        Analyzer analyzer = new IKSynonymsAnalyzer5x();
        TokenStream tokenStream = analyzer.tokenStream("test", word);
        OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
        tokenStream.reset();
        while (tokenStream.incrementToken()) {
            System.out.println(offsetAttribute.toString());
        }

    }


    private void testIK(String word) throws IOException {
        Analyzer analyzer = new IKAnalyzer5x(true);
        TokenStream tokenStream = analyzer.tokenStream("test", word);
        OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
        tokenStream.reset();
        while (tokenStream.incrementToken()) {
            System.out.println(offsetAttribute.toString());
        }
    }

    public void study() throws IOException, InterruptedException {
        InputStream resourceAsStream = App.class.getClassLoader().getResourceAsStream("json333.json");
        BufferedReader reader = new BufferedReader(new InputStreamReader(resourceAsStream));
        StringBuilder jsonString = new StringBuilder();
        String string;
        while ((string = reader.readLine()) != null) {
            jsonString.append(string);
        }
        reader.close();

        List list = JSON.parseArray(jsonString.toString());
        for (Object o : list) {
            Map map = (Map) o;
            String cid = (String) map.get("cid");
            String cName = (String) map.get("keyword");
            String desc = (String) map.get("desc");
            addIndex(cid, cName, desc);
        }

    }

    public void getDate() throws IOException, InterruptedException {
        InputStream resourceAsStream = App.class.getClassLoader().getResourceAsStream("cidkeyworditemids.txt");
        BufferedReader reader = new BufferedReader(new InputStreamReader(resourceAsStream));
        String jsonString;
        while ((jsonString = reader.readLine()) != null) {
            Map map = JSON.parseObject(jsonString, Map.class);
            String cid = (String) map.get("cid");
            String cName = (String) map.get("keyword");
            List<String> itemIds = (List<String>) map.get("itemIds");
            StringBuilder stringBuilder = new StringBuilder();
            for (String itemId : itemIds) {
                String desc = getDesc(itemId);
                stringBuilder.append(desc).append(",");
                Thread.sleep(2000);
            }
            Map data = new HashMap<>();
            data.put("cid", cid);
            data.put("cName", cName);
            data.put("desc", stringBuilder.toString());
            String datajson = JSON.toJSONString(data);
            System.out.println(datajson);
            FileOutputStream out = new FileOutputStream("C:\\Users\\User\\IdeaProjects\\zql\\src\\main\\resources\\temp.json", true);
            datajson += ",\r\n";
            out.write(datajson.getBytes());
            out.close();
            Thread.sleep(60000);
        }
    }

    private String getDesc(String itemId) throws IOException, InterruptedException {
        String itemUrl = "https://detail.1688.com/offer/" + itemId + ".html";
        String desc = null;
        try {
            org.jsoup.nodes.Document document = Jsoup.connect(itemUrl).referrer("https://m.1688.com/").get();
            Elements title = document.getElementsByAttributeValue("name", "keywords");
            desc = title.attr("content");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("wait 10s " + itemId);
            Thread.sleep(10000);
            return getDesc(itemId);
        }

        if (desc == null || "".equals(desc)) {
            System.out.println("wait 600s");
            Thread.sleep(600000);
            return getDesc(itemId);
        }

        return desc;
    }

    //////////////////////////////////////////////////////////////////////////////////////

    public void testSaveIndex() throws IOException {
        saveIndex("12344567", "abc", "主打");
        selectAll();
    }

    private void saveIndex(String cid, String cName, String desc) throws IOException {
        Directory directory = FSDirectory.open(Paths.get(indexPath2));

        IndexReader indexReader = DirectoryReader.open(directory);

        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        Query query = new TermQuery(new Term("cName", cName));

        TopDocs topDocs = indexSearcher.search(query, 10);

        if (topDocs.totalHits == 0) {
            addIndex(cid, cName, desc);
        } else if (topDocs.totalHits == 1){
            ScoreDoc scoreDoc = topDocs.scoreDocs[0];
            String oldDesc = indexSearcher.doc(scoreDoc.doc).get("desc");
            updateIndex(cid, cName, desc, oldDesc);
        } else {
            System.out.println("出现重复索引");
        }
    }

    private void addIndex(String cid, String cName, String desc) throws IOException {

        Directory directory = FSDirectory.open(Paths.get(indexPath2));

        IKAnalyzer5x analyzer = new IKAnalyzer5x();

        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);

        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

        Document document = new Document();
        document.add(new TextField("cid", cid, Field.Store.YES));
        document.add(new TextField("cName", cName, Field.Store.YES));
        document.add(new TextField("desc", desc, Field.Store.YES));

        indexWriter.addDocument(document);

        indexWriter.close();
    }

    private void updateIndex(String cid, String cName, String desc, String oldDesc) throws IOException {

        Directory directory = FSDirectory.open(Paths.get(indexPath2));

        IKAnalyzer5x analyzer = new IKAnalyzer5x();

        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);

        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

        Document document = new Document();
        document.add(new TextField("cid", cid, Field.Store.YES));
        document.add(new TextField("cName", cName, Field.Store.YES));
        document.add(new TextField("desc",  oldDesc + desc, Field.Store.YES));

        indexWriter.updateDocument(new Term("cName", cName), document);

        indexWriter.close();
    }

    @Test
    public void deleteIndex() throws IOException {
        Directory directory = FSDirectory.open(Paths.get(indexPath2));

        IKAnalyzer5x analyzer = new IKAnalyzer5x();

        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);

        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

        indexWriter.deleteDocuments(new Term("cName", "abc"));

        indexWriter.close();
    }

    public void searchCat(String keyword) throws IOException, ParseException {

        Directory directory = FSDirectory.open(Paths.get(indexPath2));

        IndexReader indexReader = DirectoryReader.open(directory);

        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        QueryParser parser = new QueryParser("desc", new IKAnalyzer5x());

        Query query = parser.parse(keyword);

        TopDocs topDocs = indexSearcher.search(query, 5);

        System.out.println("查询结果总记录数：" + topDocs.totalHits);

        for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
            int docId = scoreDoc.doc;

            Document document = indexSearcher.doc(docId);
            System.out.println(scoreDoc.score);
            System.out.println(document.get("cid"));
            System.out.println(document.get("cName"));
            System.out.println(document.get("desc"));
            System.out.println("====================================");
        }

        indexReader.close();
    }

    public void selectAll() throws IOException {
        Directory directory = FSDirectory.open(Paths.get(indexPath2));

        IndexReader indexReader = DirectoryReader.open(directory);

        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        int count = indexReader.maxDoc();

        for (int i = 0; i < count; i++) {
            int docId = i;
            Document document = indexSearcher.doc(docId);
            System.out.println(document.get("cid"));
            System.out.println(document.get("cName"));
            System.out.println(document.get("desc"));
            System.out.println("====================================");
        }

        indexReader.close();
    }

    //////////////////////////////////////////////////////////////////////////////////////


    public static void search() throws IOException {
        Directory directory = FSDirectory.open(Paths.get(indexPath));

        IndexReader indexReader = DirectoryReader.open(directory);

        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        Query query = new TermQuery(new Term("fileName", "associate.html"));

        TopDocs topDocs = indexSearcher.search(query, 10);

        System.out.println("查询结果总记录数：" + topDocs.totalHits);

        for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
            int docId = scoreDoc.doc;

            Document document = indexSearcher.doc(docId);
            System.out.println(scoreDoc.score);
            System.out.println(document.get("fileName"));
            System.out.println(document.get("filePath"));
            System.out.println(document.get("fileSize"));
        }

        indexReader.close();
    }


    public static void createIndex() throws Exception {
        Directory directory = FSDirectory.open(Paths.get(indexPath));

        IKAnalyzer analyzer = new IKAnalyzer();

        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);

        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

        String sourcePath = "C:\\Users\\User\\IdeaProjects\\tm\\app\\views";
        File file = new File(sourcePath);
        FileUtil.eachFileDir(file, (f) -> {
            String fileName = f.getName();
            String filePath = f.getPath();
            String fileContent = FileUtil.readFileToString(f);
            Long fileSize = f.length();
            Document document = new Document();
            document.add(new TextField("fileName", fileName, Field.Store.YES));
            document.add(new StoredField("filePath", filePath));
            document.add(new TextField("fileContent", fileContent, Field.Store.NO));
            document.add(new LongField("fileSize", fileSize, Field.Store.YES));
            indexWriter.addDocument(document);
        });

        indexWriter.close();
    }
}
